package main

import "fmt"

func main() {
	//测试传递参数
	fmt.Println(parametersAndReturns(5, 5))

	//测试可变参数
	myfun(1, 2, 3, 4, 5)

	//测试值传递
	arr := [4]int{1, 2, 3, 4} //定义一个数组
	fmt.Println("传递前的数据", arr)
	upDataValue(arr)             //将arr传递进去
	fmt.Println("传递后修改后数据", arr) //得到结论 值传递是拷贝动作，在函数内部自己生成一个新的变量，将参数的值拷贝进去，修改数据对原始的数据没有影响

	//测试引用传递
	//切片，可以扩容的数组，和数组的定义很像，切片的定义不需要写大小，如果在定义数组的时候不写大小就是定义切片
	s1 := []int{1, 2, 3}
	fmt.Println("传递前的数据", s1)
	upDataAdress(s1)            //将切片传递进去
	fmt.Println("传递后修改后数据", s1) //得到结论，将s1传递给方法参数s2的时候，s1会将内存空间的值传递给s2，此时s2指向的内存空间就跟s1一致，修改s2内存空间的值，s1也就会跟着变化
}

// 参数和返回类型
func parametersAndReturns(a int, b int) (t1 int, t2 int) { //前面的()包含的是参数，参数中参数名在前面，参数类型在后面，后面的()包含返回的参数，参数前面是参数名，后面是参数类型
	return a + b, a - b //有多个返回的参数用,隔开
}

// 可变参数
// 一个函数的参数类型确定，但是个数不确定，就可以使用可变参数
// 如果一个函数的参数是可变参数，同时还存在其他参数，可变参数要放在列表的最后，一个函数参数列表中最多只有一个可变参数
func myfun(args ...int) {
	println(len(args)) //输出参数的长度
	for i := 0; i < len(args); i++ {
		fmt.Println(args[i])
	}

}

// 参数传递
// 值类型：操作的是数据本身，int，string，bool，float等基础类型 array数组，struct结构体
func upDataValue(s2 [4]int) {
	s2[2] = 10
}

// 引用类型：操作的数是数据的地址 slice切片，map，chan
func upDataAdress(s2 []int) {
	s2[2] = 10
}
